<template>
  <el-card shadow="always" :body-style="{ padding: '20px' }">
    <CategorySelector :disabled="!isShowList"></CategorySelector>
  </el-card>

  <el-card
    shadow="always"
    :body-style="{ padding: '20px' }"
    style="margin-top: 20px"
  >
    <!-- 这个div就是我们平台属性列表的东西 -->
    <div v-show="isShowList">
      <el-button
        type="primary"
        size="default"
        icon="ele-Plus"
        style="margin-bottom: 20px"
        @click="showAddDiv"
        >添加属性</el-button
      >
      <el-table border stripe :data="attrList">
        <el-table-column
          label="序号"
          type="index"
          width="80"
          align="center"
        ></el-table-column>
        <el-table-column
          label="属性名称"
          width="150"
          prop="attrName"
        ></el-table-column>
        <el-table-column label="属性名称列表">
          <template v-slot="{ row }">
            <el-tag
              type="danger"
              size="default"
              v-for="attrValue in row.attrValueList"
              :key="attrValue.id"
            >
              {{ attrValue.valueName }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150">
          <template v-slot="{ row }">
            <el-button
              type="warning"
              size="small"
              icon="ele-Edit"
              title="修改"
              @click="showUpdateDiv(row)"
            ></el-button>

            <el-popconfirm
              :title="`你确认删除${row.attrName}吗？`"
              @confirm="deleteAttr(row)"
            >
              <template #reference>
                <el-button
                  type="danger"
                  size="small"
                  icon="ele-Delete"
                  title="删除"
                ></el-button
              ></template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 这个div对应的就是添加修改的界面 -->
    <div v-show="!isShowList">
      <el-form :inline="true">
        <el-form-item label="属性名">
          <el-input
            placeholder="请输入属性名"
            v-model="attrForm.attrName"
          ></el-input>
        </el-form-item>
      </el-form>
      <el-button
        type="primary"
        @click="addAttrValue"
        :disabled="!attrForm.attrName"
        >添加属性值</el-button
      >
      <el-button @click="isShowList = true">取消</el-button>
      <el-table
        border
        stripe
        :data="attrForm.attrValueList"
        style="margin: 15px 0 15px"
      >
        <el-table-column
          label="序号"
          type="index"
          width="80"
          align="center"
        ></el-table-column>
        <el-table-column label="属性值名称" prop="attrValueList">
          <template v-slot="{ row, $index }">
            <!-- keyup中内联blur -->
            <el-input
              @blur="toLook(row, $index)"
              @keyup.enter="$event.target.blur()"
              v-if="row.isEdit"
              v-model="row.valueName"
              autofocus="true"
              placeholder="请输入属性值"
              size="small"
              ref="inputRef"
            />
            <p style="width: 100%" v-else @click="toEdit(row)">
              {{ row.valueName }}
            </p>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row, $index }">
            <el-popconfirm
              :title="`你确认删除${row.valueName}吗？`"
              @confirm="attrForm.attrValueList.splice($index, 1)"
            >
              <template #reference>
                <el-button
                  type="danger"
                  size="small"
                  icon="ele-Delete"
                  title="删除属性值"
                ></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-button type="primary" @click="save">保存</el-button>
      <el-button @click="isShowList = true">取消</el-button>
    </div>
  </el-card>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { ElMessage } from "element-plus";
import type Item from "@/layout/components/Sidebar/Item";
export default defineComponent({
  name: "Attr",
});
</script>
<script lang="ts" setup>
import { watch, ref, nextTick } from "vue";
import { useCategoryStore } from "@/stores/category";
import { storeToRefs } from "pinia";
import attrApi, { type AttrData, type AttrValueData } from "@/api/attr";
// 按需引入lodash
import cloneDeep from "lodash/cloneDeep";
// 监听三级菜单id变化
const categoryStore = useCategoryStore();
const { category3Id, category2Id, category1Id } = storeToRefs(categoryStore);

const attrList = ref<AttrData[]>([]);

// 请求属性列表数据方法
const getAttrList = async () => {
  try {
    const result = await attrApi.getList(
      category1Id.value as number,
      category2Id.value as number,
      category3Id.value as number
    );
    attrList.value = result;
  } catch (error) {}
};

// 但是3级id发生变化  可能是这些情况
// 一开始没有，后面有了
// 一开始有，后面没了
// 一开始有，后来值变了
watch(
  category3Id,
  (newVal, oldVal) => {
    if (newVal != "") {
      // 调用请求属性列表数据方法
      getAttrList();
    } else {
      attrList.value = [];
    }
  },
  {
    immediate: true,
  }
);

// 平台属性的添加
const isShowList = ref(true);
// 定义添加属性数据
const attrForm = ref<AttrData>({
  attrName: "",
  attrValueList: [],
  categoryId: "",
  categoryLevel: 3, //固定就是3级分类的id
});
// 点击添加
const showAddDiv = () => {
  isShowList.value = false;
  // 重置attrForm
  attrForm.value = {
    attrName: "",
    attrValueList: [],
    categoryId: category3Id.value, //再点击时获取id不会存在挂载完成还没获取到的情况
    categoryLevel: 3,
  };
};
// 获取input组件对象
const inputRef = ref();

// 添加属性方法
const addAttrValue = () => {
  attrForm.value.attrValueList.push({
    attrId: attrForm.value.id, // 添加时是undefined，修改为属性id
    valueName: "",
    isEdit: true, // 用于条件渲染，新添加的刚一进入是input
  });
  nextTick(() => {
    // 点击添加自动获取焦点
    inputRef.value.focus();
  });
};

// 点击修改属性方法
// 在这里面需要遍历属性的所有已存在的属性值，添加isedit=false
const showUpdateDiv = (row: AttrData) => {
  isShowList.value = false;
  // 防止点击取消依旧改变原有属性，所以使用深拷贝
  attrForm.value = cloneDeep(row);
  attrForm.value.attrValueList.forEach((item) => (item.isEdit = false));
};

// 点击span切换input
const toEdit = (row: AttrValueData) => {
  row.isEdit = true;

  // 点击span自动获取焦点
  // vue当中数据改变是同步的
  // 页面的改变是异步的
  // 数据改变会引起页面改变
  // 等待页面更新完成，再去执行回调
  nextTick(() => {
    inputRef.value.focus();
  });
};

// 失去焦点input切换span
const toLook = (row: AttrValueData, index: number) => {
  // 判断输入的数据是不是空白，或者根本没输入
  if (!row.valueName || !row.valueName.trim()) {
    ElMessage.error("输入的数据不能为空");
    // 输入内容不合法则直接删除input框
    attrForm.value.attrValueList.splice(index, 1);
    return;
  }
  // 判断输入的数据是不是和除了自己以外的已存在属性值名称重复
  let isRepect = attrForm.value.attrValueList.some((item) => {
    // 排除自己
    if (item !== row) {
      return item.valueName === row.valueName;
    }
  });
  if (isRepect) {
    ElMessage.error("输入的数据不能重复");
    // row.valueName = "";
    attrForm.value.attrValueList.splice(index, 1);
    return;
  }

  row.isEdit = false;
};

// 点击保存按钮
const save = async () => {
  let attr = attrForm.value;
  // 保存的不能为空串，去除isEdit
  attr.attrValueList = attr.attrValueList.filter((item) => {
    if (item.valueName !== "") {
      delete item.isEdit;
      return true;
    }
  });
  // 如果属性列表没有属性值，则不发送请求
  if (attr.attrValueList.length === 0) {
    return;
  }
  try {
    await attrApi.addOrUpdate(attr);
    ElMessage.success("保存平台属性成功");
    isShowList.value = true;
    getAttrList();
  } catch (error) {
    ElMessage.error("保存失败");
    isShowList.value = true;
  }
};

// 删除平台属性
const deleteAttr = async (row: AttrData) => {
  try {
    await attrApi.delete(row.id as number);
    ElMessage.success("删除平台属性成功");
    getAttrList();
  } catch (error) {
    ElMessage.error("删除失败");
  }
};
</script>

<style lang="less" scoped></style>
